<template>
    <div class="live-player-container">
      <!-- Video.js播放器 -->
      <video
        ref="videoElement"
        :id="playerId"
        class="video-js vjs-default-skin"
        :class="{ 'vjs-custom-controls': !showControls }"
        preload="auto"
        data-setup="{}"
      >
        <p class="vjs-no-js">
          要查看此视频，请启用 JavaScript，并考虑升级到
          <a href="https://videojs.com/html5-video-support/" target="_blank">
            支持HTML5视频的浏览器
          </a>
        </p>
      </video>
      
      <!-- 加载状态 -->
      <div v-if="loading" class="loading-overlay">
        <div class="loading-spinner"></div>
        <p class="loading-text">加载中...</p>
      </div>
      
      <!-- 错误状态 -->
      <div v-if="error" class="error-overlay">
        <div class="error-icon">⚠️</div>
        <p class="error-text">{{ error }}</p>
        <button @click="retry" class="retry-btn">重试</button>
        <!-- <button @click="fallbackToVideoJs" class="retry-btn" style="margin-top: 8px; background: #52c41a;">
          使用Video.js播放
        </button> -->
      </div>
      
      <!-- LIVE指示器 -->
      <div v-if="!loading && !error && isPlaying && isLive" class="live-indicator">
        <span class="live-dot"></span>
        LIVE
      </div>
  
      <!-- 摄像头名称显示 -->
      <div v-if="!loading && !error && cameraName" class="camera-name-overlay">
        {{ cameraName }}
      </div>
      
      <!-- 信号强度指示器 -->
      <div v-if="!loading && !error && isPlaying" class="signal-indicator">
        <div class="signal-bars">
          <div class="bar" :class="{ active: signalStrength >= 1 }"></div>
          <div class="bar" :class="{ active: signalStrength >= 2 }"></div>
          <div class="bar" :class="{ active: signalStrength >= 3 }"></div>
          <div class="bar" :class="{ active: signalStrength >= 4 }"></div>
        </div>
      </div>
      
      <!-- 自定义控制栏 -->
      <div v-if="!showControls && !loading && !error" class="custom-controls" @click.stop>
        <button @click.stop="togglePlay" class="control-btn play-btn" title="播放/暂停">
          <svg v-if="!isPlaying" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
            <path d="M8 5v14l11-7z"/>
          </svg>
          <svg v-else width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
            <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
          </svg>
        </button>
        
        <div class="volume-control">
          <button @click.stop="toggleMute" class="control-btn volume-btn" :title="isMuted ? '取消静音' : '静音'">
            <svg v-if="!isMuted && volume > 0.5" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>
            </svg>
            <svg v-else-if="!isMuted && volume > 0" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"/>
            </svg>
            <svg v-else width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>
            </svg>
          </button>
          
          <!-- 音量滑块 -->
          <div class="volume-slider-container" v-show="!isMuted">
            <input 
              type="range" 
              min="0" 
              max="1" 
              step="0.1" 
              :value="volume" 
              @input="handleVolumeChange"
              @click.stop
              class="volume-slider"
            />
          </div>
        </div>
        
        <div class="quality-control">
          <select 
            v-model="currentQuality" 
            @change="changeQuality" 
            @click.stop
            class="quality-select"
            title="画质选择"
          >
            <option value="auto">自动</option>
            <option value="1080p">1080P</option>
            <option value="720p">720P</option>
            <option value="480p">480P</option>
          </select>
        </div>
        
        <!-- 进度条 -->
        <div class="progress-container" v-if="!isLive">
          <input 
            type="range" 
            min="0" 
            :max="duration" 
            :value="currentTime" 
            @input="handleSeek"
            @click.stop
            class="progress-slider"
          />
        </div>
        
        <div class="time-display">
          {{ formatTime(currentTime) }} / {{ isLive ? 'LIVE' : formatTime(duration) }}
        </div>
        
        <!-- 全屏按钮 -->
        <button @click.stop="toggleFullscreen" class="control-btn fullscreen-btn" title="全屏">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
            <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>
          </svg>
        </button>
      </div>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
  
  // 声明全局类型
  declare global {
    interface Window {
      videojs: any
      Hls: any
      flvjs: any
    }
  }
  
  // Props
  interface Props {
    videoUrl: string
    autoPlay?: boolean
    muted?: boolean
    loop?: boolean
    showControls?: boolean
    isLive?: boolean
    cameraName?: string
  }
  
  const props = withDefaults(defineProps<Props>(), {
    autoPlay: false,
    muted: false,
    loop: true,
    showControls: false,
    isLive: false,
    cameraName: ''
  })
  
  // Emits
  const emit = defineEmits<{
    play: []
    pause: []
    ended: []
    error: [error: string]
    ready: []
    timeupdate: [data: { currentTime: number; duration: number }]
  }>()
  
  // Refs
  const videoElement = ref<HTMLVideoElement>()
  const playerId = ref(`player_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`)
  let player: any = null
  let flvPlayer: any = null
  
  // 响应式数据
  const loading = ref(false)
  const error = ref<string>('')
  const isPlaying = ref(false)
  const currentTime = ref(0)
  const duration = ref(0)
  const volume = ref(0.8)
  const isMuted = ref(props.muted)
  const signalStrength = ref(4)
  const currentQuality = ref('auto')
  const cameraName = ref(props.cameraName)
  const usingFlvPlayer = ref(false)
  const flvRetryCount = ref(0)
  const maxFlvRetries = 2
  
  // 计算属性
  const canPlay = computed(() => !loading.value && !error.value)
  
  // 检查Video.js是否可用
  const checkVideoJsAvailable = (): boolean => {
    return typeof window !== 'undefined' && window.videojs
  }
  
  // 检查FLV.js是否可用
  const checkFlvJsAvailable = (): boolean => {
    return typeof window !== 'undefined' && window.flvjs && window.flvjs.isSupported()
  }
  
  // 获取视频类型
  const getVideoType = (url: string): string => {
    const extension = url.split('.').pop()?.toLowerCase()
    
    switch (extension) {
      case 'mp4':
        return 'video/mp4'
      case 'webm':
        return 'video/webm'
      case 'ogg':
        return 'video/ogg'
      case 'm3u8':
        return 'application/x-mpegURL'
      case 'flv':
        return 'video/x-flv'
      default:
        return 'video/mp4'
    }
  }
  
  // 判断是否为FLV格式
  const isFlvFormat = (url: string): boolean => {
    return url.toLowerCase().includes('.flv')
  }
  
  // 加载FLV.js
  const loadFlvJs = (): Promise<void> => {
    return new Promise((resolve, reject) => {
      if (checkFlvJsAvailable()) {
        resolve()
        return
      }
  
      const script = document.createElement('script')
      script.src = 'https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js'
      script.onload = () => {
        console.log('FLV.js 加载成功')
        resolve()
      }
      script.onerror = () => {
        console.error('FLV.js 加载失败')
        reject(new Error('FLV.js 加载失败'))
      }
      document.head.appendChild(script)
    })
  }
  
  // 清理FLV播放器
  const cleanupFlvPlayer = () => {
    if (flvPlayer) {
      try {
        if (flvPlayer.destroy) {
          flvPlayer.destroy()
        }
      } catch (e) {
        console.warn('清理FLV播放器时出错:', e)
      }
      flvPlayer = null
    }
    usingFlvPlayer.value = false
  }
  
  // 初始化FLV播放器
  const initFlvPlayer = async () => {
    if (!videoElement.value || !props.videoUrl) return
  
    try {
      loading.value = true
      error.value = ''
      
      console.log('开始初始化FLV播放器...')
  
      // 加载FLV.js
      await loadFlvJs()
  
      if (!checkFlvJsAvailable()) {
        throw new Error('当前浏览器不支持FLV.js')
      }
  
      // 清理现有播放器
      cleanupFlvPlayer()
  
      await nextTick()
  
      // 检查FLV.js是否支持当前环境
      if (!window.flvjs.isSupported()) {
        throw new Error('当前浏览器不支持FLV播放')
      }
  
      // 创建FLV播放器配置
      const mediaDataSource = {
        type: 'flv',
        url: props.videoUrl,
        isLive: props.isLive,
        cors: true,
        withCredentials: false
      }
  
      const config = {
        enableWorker: false, // 禁用Worker避免跨域问题
        enableStashBuffer: !props.isLive, // 直播流禁用缓存
        stashInitialSize: props.isLive ? 64 : 128,
        autoCleanupSourceBuffer: true,
        autoCleanupMaxBackwardDuration: 30,
        autoCleanupMinBackwardDuration: 10,
        statisticsInfoReportInterval: 600,
        fixAudioTimestampGap: true,
        accurateSeek: !props.isLive,
        seekType: 'range',
        seekParamStart: 'start',
        seekParamEnd: 'end',
        rangeLoadZeroStart: false,
        lazyLoad: true,
        lazyLoadMaxDuration: 3 * 60,
        lazyLoadRecoverDuration: 30,
        deferLoadAfterSourceOpen: false,
        reuseRedirectedURL: false
      }
  
      console.log('FLV配置:', { mediaDataSource, config })
  
      // 创建FLV播放器
      flvPlayer = window.flvjs.createPlayer(mediaDataSource, config)
      
      if (!flvPlayer) {
        throw new Error('FLV播放器创建失败')
      }
  
      // 绑定到video元素
      flvPlayer.attachMediaElement(videoElement.value)
      
      // 设置视频属性
      videoElement.value.loop = props.loop
      videoElement.value.muted = props.muted
      videoElement.value.volume = volume.value
  
      // 绑定事件
      bindFlvPlayerEvents()
  
      // 加载视频
      await flvPlayer.load()
      
      usingFlvPlayer.value = true
      console.log('FLV播放器初始化成功')
      loading.value = false
      emit('ready')
  
    } catch (err) {
      console.error('FLV播放器初始化失败:', err)
      cleanupFlvPlayer()
      loading.value = false
      
      const errorMessage = err instanceof Error ? err.message : 'FLV播放器初始化失败'
      
      // 如果重试次数未达到上限，尝试重试
      if (flvRetryCount.value < maxFlvRetries) {
        flvRetryCount.value++
        console.log(`FLV播放器重试 ${flvRetryCount.value}/${maxFlvRetries}`)
        setTimeout(() => {
          initFlvPlayer()
        }, 1000)
        return
      }
      
      error.value = `${errorMessage} (已重试${maxFlvRetries}次)`
      emit('error', error.value)
    }
  }
  
  // 绑定FLV播放器事件
  const bindFlvPlayerEvents = () => {
    if (!flvPlayer || !videoElement.value) return
  
    const video = videoElement.value
  
    try {
      // 原生video事件
      video.addEventListener('play', () => {
        console.log('FLV播放开始')
        isPlaying.value = true
        updateSignalStrength()
        emit('play')
      })
  
      video.addEventListener('pause', () => {
        console.log('FLV播放暂停')
        isPlaying.value = false
        emit('pause')
      })
  
      video.addEventListener('ended', () => {
        console.log('FLV播放结束')
        isPlaying.value = false
        emit('ended')
      })
  
      video.addEventListener('timeupdate', () => {
        currentTime.value = video.currentTime || 0
        duration.value = video.duration || 0
        
        emit('timeupdate', {
          currentTime: currentTime.value,
          duration: duration.value
        })
      })
  
      video.addEventListener('volumechange', () => {
        volume.value = video.volume
        isMuted.value = video.muted
      })
  
      video.addEventListener('error', (e) => {
        console.error('FLV video元素错误:', e)
        const errorMsg = `视频播放错误: ${video.error?.message || '未知错误'}`
        handleFlvError('VIDEO_ERROR', errorMsg)
      })
  
      video.addEventListener('loadstart', () => {
        console.log('FLV开始加载')
        loading.value = true
      })
  
      video.addEventListener('canplay', () => {
        console.log('FLV可以播放')
        loading.value = false
      })
  
      video.addEventListener('loadeddata', () => {
        console.log('FLV数据加载完成')
        loading.value = false
        duration.value = video.duration || 0
      })
  
      // FLV.js特定事件
      flvPlayer.on(window.flvjs.Events.ERROR, (errorType: string, errorDetail: string, errorInfo: any) => {
        console.error('FLV.js错误:', { errorType, errorDetail, errorInfo })
        handleFlvError(errorType, errorDetail, errorInfo)
      })
  
      flvPlayer.on(window.flvjs.Events.LOADING_COMPLETE, () => {
        console.log('FLV加载完成')
        loading.value = false
      })
  
      flvPlayer.on(window.flvjs.Events.RECOVERED_EARLY_EOF, () => {
        console.log('FLV流恢复')
      })
  
      flvPlayer.on(window.flvjs.Events.MEDIA_INFO, (mediaInfo: any) => {
        console.log('FLV媒体信息:', mediaInfo)
      })
  
      flvPlayer.on(window.flvjs.Events.STATISTICS_INFO, (statisticsInfo: any) => {
        console.log('FLV统计信息:', statisticsInfo)
      })
  
    } catch (err) {
      console.error('绑定FLV事件失败:', err)
    }
  }
  
  // 处理FLV错误
  const handleFlvError = (errorType: string, errorDetail: string, errorInfo?: any) => {
    console.error('FLV播放错误:', { errorType, errorDetail, errorInfo })
    
    let errorMessage = 'FLV播放失败'
    
    // 根据错误类型提供更具体的错误信息
    switch (errorType) {
      case 'NETWORK_ERROR':
        errorMessage = '网络连接错误，请检查网络或视频源'
        break
      case 'MEDIA_ERROR':
        errorMessage = '媒体解码错误，视频格式可能不支持'
        break
      case 'OTHER_ERROR':
        errorMessage = '播放器内部错误'
        break
      default:
        errorMessage = `FLV播放错误: ${errorDetail || errorType}`
    }
    
    loading.value = false
    error.value = errorMessage
    emit('error', errorMessage)
  }
  
  // 回退到Video.js播放器
  const fallbackToVideoJs = async () => {
    console.log('回退到Video.js播放器')
    cleanupFlvPlayer()
    flvRetryCount.value = 0
    await initVideoJsPlayer()
  }
  
  // 初始化Video.js播放器
  const initVideoJsPlayer = async () => {
    if (!videoElement.value || !props.videoUrl) return
  
    try {
      loading.value = true
      error.value = ''
  
      // 检查Video.js是否已加载
      if (!checkVideoJsAvailable()) {
        throw new Error('Video.js未加载，请检查网络连接')
      }
  
      // 销毁现有播放器
      if (player) {
        try {
          player.dispose()
        } catch (e) {
          console.warn('销毁Video.js播放器时出错:', e)
        }
        player = null
      }
  
      await nextTick()
  
      // Video.js配置
      const playerOptions = {
        autoplay: props.autoPlay,
        muted: props.muted,
        loop: props.loop,
        controls: props.showControls,
        preload: 'auto',
        
        sources: [{
          src: props.videoUrl,
          type: getVideoType(props.videoUrl)
        }],
        
        fluid: true,
        responsive: true,
        aspectRatio: '16:9',
        playbackRates: [0.5, 1, 1.25, 1.5, 2],
        techOrder: ['html5'],
        
        html5: {
          hls: {
            enableLowInitialPlaylist: true,
            smoothQualityChange: true,
            overrideNative: true
          }
        }
      }
  
      // 创建Video.js实例
      player = window.videojs(videoElement.value, playerOptions)
  
      // 设置初始音量
      player.ready(() => {
        player.volume(volume.value)
        player.muted(isMuted.value)
      })
  
      // 绑定事件
      bindPlayerEvents()
  
      usingFlvPlayer.value = false
      console.log('Video.js播放器初始化成功')
      loading.value = false
      emit('ready')
  
    } catch (err) {
      console.error('Video.js播放器初始化失败:', err)
      loading.value = false
      error.value = err instanceof Error ? err.message : 'Video.js播放器初始化失败'
      emit('error', error.value)
    }
  }
  
  // 绑定Video.js播放器事件
  const bindPlayerEvents = () => {
    if (!player) return
  
    try {
      player.on('play', () => {
        console.log('Video.js播放开始')
        isPlaying.value = true
        updateSignalStrength()
        emit('play')
      })
  
      player.on('pause', () => {
        console.log('Video.js播放暂停')
        isPlaying.value = false
        emit('pause')
      })
  
      player.on('ended', () => {
        console.log('Video.js播放结束')
        isPlaying.value = false
        emit('ended')
      })
  
      player.on('timeupdate', () => {
        if (player) {
          currentTime.value = player.currentTime() || 0
          duration.value = player.duration() || 0
          
          emit('timeupdate', {
            currentTime: currentTime.value,
            duration: duration.value
          })
        }
      })
  
      player.on('volumechange', () => {
        if (player) {
          volume.value = player.volume()
          isMuted.value = player.muted()
        }
      })
  
      player.on('error', (err: any) => {
        console.error('Video.js播放错误:', err)
        loading.value = false
        
        let errorMessage = '播放失败'
        const playerError = player.error()
        
        if (playerError) {
          switch (playerError.code) {
            case 1:
              errorMessage = '视频加载被中止'
              break
            case 2:
              errorMessage = '网络错误'
              break
            case 3:
              errorMessage = '视频解码错误'
              break
            case 4:
              errorMessage = '视频格式不支持'
              break
            default:
              errorMessage = `播放错误 (${playerError.code})`
          }
        }
        
        error.value = errorMessage
        emit('error', errorMessage)
      })
  
      player.on('loadstart', () => {
        console.log('Video.js开始加载')
        loading.value = true
        error.value = ''
      })
  
      player.on('canplay', () => {
        console.log('Video.js可以播放')
        player.play()
        loading.value = false
      })
  
      player.on('loadeddata', () => {
        console.log('Video.js数据加载完成')
        loading.value = false
        if (player) {
          duration.value = player.duration() || 0
        }
      })
  
      player.on('ready', () => {
        console.log('Video.js播放器准备就绪')
        loading.value = false
      })
  
    } catch (err) {
      console.error('绑定Video.js事件失败:', err)
    }
  }
  
  // 初始化播放器（根据格式选择）
  const initPlayer = async () => {
    if (!props.videoUrl) return
  
    // 重置重试计数
    flvRetryCount.value = 0
  
    if (isFlvFormat(props.videoUrl)) {
      console.log('检测到FLV格式，使用FLV.js播放器')
      await initFlvPlayer()
    } else {
      console.log('使用Video.js播放器')
      await initVideoJsPlayer()
    }
  }
  
  // 播放控制方法
  const play = async () => {
    if (!canPlay.value) return
    
    try {
      if (usingFlvPlayer.value && videoElement.value) {
        const playPromise = videoElement.value.play()
        if (playPromise !== undefined) {
          await playPromise
        }
      } else if (player) {
        const playPromise = player.play()
        if (playPromise !== undefined) {
          await playPromise
        }
      }
    } catch (err) {
      console.error('播放失败:', err)
      error.value = '播放失败，请检查视频源'
    }
  }
  
  const pause = () => {
    try {
      if (usingFlvPlayer.value && videoElement.value) {
        videoElement.value.pause()
      } else if (player) {
        player.pause()
      }
    } catch (err) {
      console.error('暂停失败:', err)
    }
  }
  
  const stop = () => {
    try {
      if (usingFlvPlayer.value && videoElement.value) {
        videoElement.value.pause()
        videoElement.value.currentTime = 0
      } else if (player) {
        player.pause()
        player.currentTime(0)
      }
    } catch (err) {
      console.error('停止失败:', err)
    }
  }
  
  const togglePlay = () => {
    console.log('切换播放状态:', isPlaying.value)
    if (isPlaying.value) {
      pause()
    } else {
      play()
    }
  }
  
  const toggleMute = () => {
    try {
      if (usingFlvPlayer.value && videoElement.value) {
        videoElement.value.muted = !videoElement.value.muted
        isMuted.value = videoElement.value.muted
      } else if (player) {
        const newMutedState = !player.muted()
        player.muted(newMutedState)
        isMuted.value = newMutedState
      }
      console.log('切换静音状态:', isMuted.value)
    } catch (err) {
      console.error('切换静音失败:', err)
    }
  }
  
  const setVolume = (newVolume: number) => {
    try {
      const vol = Math.max(0, Math.min(1, newVolume))
      if (usingFlvPlayer.value && videoElement.value) {
        videoElement.value.volume = vol
        volume.value = vol
      } else if (player) {
        player.volume(vol)
        volume.value = vol
      }
      console.log('设置音量:', vol)
    } catch (err) {
      console.error('设置音量失败:', err)
    }
  }
  
  const handleVolumeChange = (event: Event) => {
    const target = event.target as HTMLInputElement
    const newVolume = parseFloat(target.value)
    setVolume(newVolume)
  }
  
  const seekTo = (time: number) => {
    try {
      if (usingFlvPlayer.value && videoElement.value) {
        videoElement.value.currentTime = time
      } else if (player) {
        player.currentTime(time)
      }
    } catch (err) {
      console.error('跳转失败:', err)
    }
  }
  
  const handleSeek = (event: Event) => {
    const target = event.target as HTMLInputElement
    const newTime = parseFloat(target.value)
    seekTo(newTime)
  }
  
  const toggleFullscreen = () => {
    try {
      if (player) {
        if (player.isFullscreen()) {
          player.exitFullscreen()
        } else {
          player.requestFullscreen()
        }
      } else if (videoElement.value) {
        if (document.fullscreenElement) {
          document.exitFullscreen()
        } else {
          videoElement.value.requestFullscreen()
        }
      }
    } catch (err) {
      console.error('全屏切换失败:', err)
    }
  }
  
  const changeQuality = () => {
    console.log('切换画质到:', currentQuality.value)
  }
  
  const retry = () => {
    error.value = ''
    flvRetryCount.value = 0
    initPlayer()
  }
  
  const formatTime = (seconds: number): string => {
    if (!seconds || !isFinite(seconds)) return '00:00'
    
    const mins = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  }
  
  // 模拟信号强度变化
  const updateSignalStrength = () => {
    const strengths = [2, 3, 4, 3, 4, 4, 3, 4]
    let index = 0
    
    const interval = setInterval(() => {
      if (!isPlaying.value) {
        clearInterval(interval)
        return
      }
      
      signalStrength.value = strengths[index % strengths.length]
      index++
    }, 2000)
  }
  
  // 监听摄像头名称变化
  watch(() => props.cameraName, (newName) => {
    cameraName.value = newName
  }, { immediate: true })
  
  // 监听视频URL变化
  watch(() => props.videoUrl, (newUrl) => {
    if (newUrl) {
      setTimeout(() => {
        initPlayer()
      }, 100)
    }
  }, { immediate: false })
  
  // 暴露方法给父组件
  defineExpose({
    play,
    pause,
    stop,
    togglePlay,
    setVolume,
    seekTo,
    retry,
    fallbackToVideoJs,
    player: () => player || flvPlayer
  })
  
  // 生命周期
  onMounted(() => {
    const checkAndInit = () => {
      if (props.videoUrl) {
        initPlayer()
      }
    }
    
    checkAndInit()
  })
  
  onUnmounted(() => {
    // 清理播放器资源
    if (player) {
      try {
        player.dispose()
      } catch (e) {
        console.warn('销毁Video.js播放器时出错:', e)
      }
      player = null
    }
    
    cleanupFlvPlayer()
  })
  </script>
  
  <style scoped>
  .live-player-container {
    position: relative;
    width: 100%;
    height: 100%;
    background: #000;
    border-radius: 4px;
    overflow: hidden;
  }
  
  /* 确保自定义控制栏在最上层 */
  .custom-controls {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
    padding: 12px;
    display: flex;
    align-items: center;
    gap: 12px;
    z-index: 1000 !important;
    pointer-events: auto;
  }
  
  .control-btn {
    width: 32px;
    height: 32px;
    border: none;
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    flex-shrink: 0;
    pointer-events: auto;
  }
  
  .control-btn:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: scale(1.05);
  }
  
  .control-btn:active {
    background: rgba(255, 255, 255, 0.4);
    transform: scale(0.95);
  }
  
  .volume-control {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  
  .volume-slider-container {
    display: flex;
    align-items: center;
  }
  
  .volume-slider {
    width: 60px;
    height: 4px;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  
  .volume-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
  }
  
  .volume-slider::-moz-range-thumb {
    width: 12px;
    height: 12px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
    border: none;
  }
  
  .quality-control {
    display: flex;
    align-items: center;
  }
  
  .quality-select {
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 4px;
    padding: 4px 8px;
    font-size: 12px;
    cursor: pointer;
    outline: none;
  }
  
  .quality-select option {
    background: #333;
    color: white;
  }
  
  .progress-container {
    flex: 1;
    margin: 0 12px;
  }
  
  .progress-slider {
    width: 100%;
    height: 4px;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  
  .progress-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
  }
  
  .progress-slider::-moz-range-thumb {
    width: 12px;
    height: 12px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
    border: none;
  }
  
  .time-display {
    color: white;
    font-size: 12px;
    font-family: monospace;
    flex-shrink: 0;
    min-width: 80px;
    text-align: center;
  }
  
  /* 隐藏Video.js默认控制栏当使用自定义控制栏时 */
  .video-js.vjs-custom-controls .vjs-control-bar {
    display: none !important;
  }
  
  .video-js.vjs-custom-controls .vjs-big-play-button {
    display: none !important;
  }
  
  /* 确保Video.js不会阻止自定义控制栏的事件 */
  .video-js.vjs-custom-controls {
    pointer-events: none;
  }
  
  .video-js.vjs-custom-controls .vjs-tech {
    pointer-events: auto;
  }
  
  .loading-overlay,
  .error-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.8);
    color: white;
    z-index: 10;
  }
  
  .loading-spinner {
    width: 40px;
    height: 40px;
    border: 3px solid rgba(255, 255, 255, 0.3);
    border-top: 3px solid #1890ff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 12px;
  }
  
  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
  
  .loading-text,
  .error-text {
    font-size: 14px;
    margin: 0;
    text-align: center;
  }
  
  .error-icon {
    font-size: 48px;
    margin-bottom: 12px;
  }
  
  .retry-btn {
    margin-top: 12px;
    padding: 8px 16px;
    background: #1890ff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    transition: background 0.2s;
  }
  
  .retry-btn:hover {
    background: #40a9ff;
  }
  
  .live-indicator {
    position: absolute;
    top: 12px;
    left: 12px;
    display: flex;
    align-items: center;
    gap: 6px;
    background: rgba(255, 77, 79, 0.9);
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: bold;
    z-index: 15;
  }
  
  .live-dot {
    width: 8px;
    height: 8px;
    background: white;
    border-radius: 50%;
    animation: blink 1s infinite;
  }
  
  @keyframes blink {
    0%, 50% { opacity: 1; }
    51%, 100% { opacity: 0.3; }
  }
  
  .signal-indicator {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 15;
  }
  
  .signal-bars {
    display: flex;
    gap: 2px;
    align-items: end;
  }
  
  .bar {
    width: 3px;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 1px;
    transition: background 0.3s;
  }
  
  .bar:nth-child(1) { height: 8px; }
  .bar:nth-child(2) { height: 12px; }
  .bar:nth-child(3) { height: 16px; }
  .bar:nth-child(4) { height: 20px; }
  
  .bar.active {
    background: #52c41a;
    animation: signal-pulse 2s infinite;
  }
  
  @keyframes signal-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.7; }
  }
  
  .camera-name-overlay {
    position: absolute;
    top: 12px;
    left: 12px;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 6px 12px;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 500;
    z-index: 16;
    max-width: 60%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    backdrop-filter: blur(4px);
  }
  
  /* 当有LIVE指示器时，摄像头名称向下偏移 */
  .live-indicator + .camera-name-overlay {
    top: 48px;
  }
  
  /* 响应式设计 */
  @media (max-width: 768px) {
    .custom-controls {
      padding: 8px;
      gap: 8px;
    }
    
    .control-btn {
      width: 28px;
      height: 28px;
    }
    
    .time-display {
      font-size: 11px;
      min-width: 70px;
    }
    
    .quality-select {
      font-size: 11px;
      padding: 2px 6px;
    }
    
    .volume-slider {
      width: 40px;
    }
    
    .progress-container {
      margin: 0 8px;
    }
    
    .camera-name-overlay {
      font-size: 12px;
      padding: 4px 8px;
      max-width: 70%;
    }
  }
  </style>
  